#include <map>
#include <vector>
#include <regex>
#include "cppjieba/include/cppjieba/Jieba.hpp"
using namespace std;

vector<string> reserved_keywords {
	"{",

	"了别", "了当", "了得", "了断",
	"了无", "了愿", "了债", "了办",
	"了事", "了然", "了却", "了结",
	"了解", "了如", "了不得", "了不起",
	"说了算", "铁了心", "铁了事", "开了窍",
	"没了", "乱了套", "横了心", "不了",
	"不甚了然", "知了", "完了", "算了",
	"罢了", "肿么了", "过奖了", "好极了",
	"大不了", "免不了",

	"地面", "的地", "有地", "地球",
	"地空", "地名", "地貌", "地区",
	"地理", "地块", "地形", "地势",
	"地位", "地图", "地铁", "地狱",
	"地盘", "地皮", "地坪", "地上",
	"地点", "地带", "地方", "地缝",
	"地瓜", "地火", "地精", "地库",
	"地雷", "地址", "地震", "地质",
	"地下", "地产", "地层", "地板",
	"地表", "地暖", "土地", "天地",
	"田地", "境地", "圈地", "外地",
	"洼地", "入地", "异地", "盆地",
	"平地", "湿地", "圣地", "实地",
	"腹地", "各地", "工地", "高地",
	"耕地", "该地", "海地", "基地",
	"绝地", "接地", "空地", "落地",
	"领地", "绿地", "陆地", "林地",
	"之地", "阵地", "占地", "质地",
	"驻地", "场地", "产地", "此地",
	"草地", "本地", "白地", "内地",
	"拿地", "农地", "墓地", "某地",

	"得体", "得意", "得到", "得分",
	"得过", "得很", "得奖", "得空",
	"得了", "得证", "得知", "得罪",
	"得主", "得出", "取得", "赢得",
	"使得", "锻得", "懂得", "获得",
	"觉得", "解得", "记得", "懒得",
	"值得", "显得", "测得", "变得",
	"不得", "彼得", "难得", "没得",
	"免得",

	"可的", "打的", "的卢",

	// Comments from https://bilibili.com/
	"考古", "梦开始的地方", "泪目", "十个泪目九个笑，还有一个在狂笑",
	"十个泪目一个笑，还有九个在狂笑", "公屏",
	"核善", "核平", "核蔼", "以核为贵",
	"蘑菇蛋", "蘑菇弹", "以核服人", "以德服人",
	"以理服人",
	"有生之年", "爷青回", "爷青结", "失踪人口回归",
	"up主", "UP主", "Up主", "零零后",
	"00后", "鸽视频", "阿婆主",
	"富贵色", "会员色",
	"字母君", "字幕菌", "野生字幕菌",
	"哈哈哈哈", "红红火火恍恍惚惚",

	"啊我死了", "awsl", "AWSL", "Awsl",
	"阿伟死了", "阿伟瘦了", "啊我是驴",

	"武汉加油", "有内味了", "双厨狂喜", "爷青回",
	"禁止套娃",

	"xswl", "XSWL", "Xswl", "hhh",
	"lol", "LOL", "Lol", "rofl",
	"Rofl", "ROFL", "Hahaha", "hahaha",
	"HaHaHa", "HAHAHA",

	"哔哩哔哩", "bilibili", "Bilibili", "BiliBili",
	"BILIBILI",

	// ...（和谐）
	"发生肾么事了", "发生甚么事了",
	"把颈椎练坏了",
	"年轻人不讲武德", "不讲武德", "有备而来",
	"来骗", "来偷袭", "耗子尾汁",
	"闪电五连鞭",
	"金坷垃", "奥利给",

	"亿遍", "亿点点",
	"橘里橘气", "紫气东来", "磕到了",
};

map<string, vector<string>> translation_map {
    {"什么", {"啥", "啥子", "肾么", "甚么"}},
    {"怎么", {"咋"}},
    {"炒饭", {"抄饭", "吵饭"}},
    {"充气", {"冲气"}},
    {"零售", {"另售"}},
    {"装潢", {"装璜", "装黄"}},
    {"盒饭", {"合饭"}},
    {"菠萝", {"波萝"}},
    {"鸡蛋", {"鸡旦"}},
    {"停车", {"仃车"}},
    {"零", {"〇"}},
    {"秘籍", {"秘笈"}},
    {"快餐", {"快歺"}}
};

map<string, vector<string>>::iterator iter;

bool endswith(string s,string sub)
{
    return s.rfind(sub)==(s.length()-sub.length())?1:0;
}

vector<string> cut(string s)
{
	const char* const DICT_PATH = "cppjieba/dict/jieba.dict.utf8";
    const char* const HMM_PATH = "cppjieba/dict/hmm_model.utf8";
    const char* const USER_DICT_PATH = "cppjieba/dict/user.dict.utf8";
    const char* const IDF_PATH = "cppjieba/dict/idf.utf8";
    const char* const STOP_WORD_PATH = "cppjieba/dict/stop_words.utf8";

    cppjieba::Jieba jieba(DICT_PATH,
        HMM_PATH,
        USER_DICT_PATH,
        IDF_PATH,
        STOP_WORD_PATH);
    vector<string> words;
    vector<cppjieba::Word> jiebawords;

    jieba.Cut(s, words, true);
	return words;
}

void find_and_replace_all(string &data, string toSearch, string replaceStr)
{
    size_t pos = data.find(toSearch);
    while (pos != std::string::npos)
    {
        data.replace(pos, toSearch.size(), replaceStr);
        pos = data.find(toSearch, pos + replaceStr.size());
    }
}

string join(vector<string> arr)
{
	string result = "";
	for (string str: arr)
	{
		result += str;
	}
	return result;
}

class Translation
{
public:
    string to_translate;
    string translate();
};

string Translation::translate()
{
    bool question_mark;
    if (endswith(to_translate, "？"))
	{
        to_translate = to_translate.substr(0, to_translate.size() - string("？").size());
        question_mark = true;
    }
	else if (endswith(to_translate, "?"))
	{
        to_translate = to_translate.substr(0, to_translate.size() - 1);
        question_mark = true;
    }
    string result;
	string pattern = "(.*?是)((啥|什么)(玩意|东西|意思)?(儿|呢|呀|啊)?|谁)$";
    regex r (pattern);
    smatch regex_results;
    if (regex_match(to_translate, regex_results, r))
	{
        if(regex_results[2] == "谁")
            result = to_translate;
        else
		{
            if (regex_results[4] != "意思")
                result = string(regex_results[1]) + "什么";
            else
                result = string(regex_results[1]) + "什么意思";
        }
		return result;
    }

	result = to_translate;
	char* format;
	for (int i = 0; i < reserved_keywords.size(); i++)
	{
		sprintf(format, "{k@#%d}", i);
		find_and_replace_all(result, reserved_keywords[i], format);
	}
	vector<string> words = cut(to_translate);

    for(iter = translation_map.begin(); iter != translation_map.end(); iter++)
	{
		vector<string> values = iter -> second;
		for (string informal : values)
		{
			for (int i = 0; i < words.size(); i++)
			{
				if (words[i] == informal)
				{
					words[i] = iter -> first;
				}
			}
		}
    }

	result = join(words);

	for (int i = 0; i < reserved_keywords.size(); i++)
	{
		sprintf(format, "{k@#%d}", i);
		find_and_replace_all(result, format, reserved_keywords[i]);
	}

    return result;
}
